package com.yuyu.commons.security;

import cn.hutool.core.codec.Base64Decoder;
import com.alibaba.fastjson.JSON;
import com.yuyu.commons.annotation.NoAuth;
import com.yuyu.commons.exception.TokenException;
import com.yuyu.commons.toolKit.JwtUtil;
import io.jsonwebtoken.Claims;
import jodd.util.StringUtil;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @author
 * @version 1.0
 * @description: 权限拦截器
 * @date 2022/8/3 15:18
 */
public class AuthenticationInterceptor implements HandlerInterceptor {

    public static final String HEARD_LOGIN="F-SHOP-LOGIN";
    public static final String TRACE_ID="x-b3-traceid";
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            NoAuth noAuth = handlerMethod.getMethodAnnotation(NoAuth.class);
            if (noAuth == null) {
                String jwt = request.getHeader(HEARD_LOGIN);
                String traceId = request.getHeader(TRACE_ID);
                if (StringUtil.isNotEmpty(jwt)) {
                    Claims claims = JwtUtil.parseJWT(jwt);
                    String subject = claims.getSubject();
                    LoginUser loginUser = JSON.parseObject(subject, LoginUser.class);
                    loginUser.setTraceId(traceId);
                    //验证token是否正确
                    verifyToken(loginUser,claims);
                    //设置token
                    LoginContext.setUser(loginUser);
                }else {
                    throw new TokenException("token信息不存在,请稍后再试!");
                }
            }
        }
        return true;
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        LoginContext.clear();
    }

    private void verifyToken(LoginUser loginUser,Claims claims) {
        //可以通过查库来判断id和phone
        if (Objects.isNull(loginUser.getUserId()) ||
            StringUtil.isBlank(loginUser.getPhone()) ||
            Objects.isNull(loginUser.getLoginTime())){
            throw new TokenException("token信息缺失,校验失败!");
        }

        //校验时间是否过期
        long now = System.currentTimeMillis();
        if (now> loginUser.getLoginTime() + claims.getExpiration().getTime()){
            throw new TokenException("登录信息过期,请重新登录!");
        }

    }

    public static void main(String[] args) {
        String key="wCcwQvaTaIWSFHRWp3OxA7==";
        String token = new String(Base64Decoder.decode(key), StandardCharsets.UTF_8);
        System.out.println(token);
    }
}
